package demo.forms;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.imageio.ImageIO;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import webdriver.CommonFunctions;
import webdriver.elements.Button;
import webdriver.elements.ComboBox;
import webdriver.elements.TextBox;
import demo.items.Game;

/**
 * Класс для работы со списками игр
 */
public class GamesListPage extends SteamBasePage {

	// шаблоны локаторов
	public static String dicsountsListLocator = "//div[@id='tab_Discounts_items']";
	public static String discoutItemLocator = "//div[contains(@id,'tab_row_Discounts')]";
	private static String dateLtr = "//select[@name='%1$s']";

	// элементы страницы
	private static Button btnMediaScrollBar = new Button(divIdContainsLocator, "highlight_slider", "Слайдер");
	private static TextBox txbStripLine	 = new TextBox(divIdContainsLocator, "highlight_strip", "Список медиа контента");

	// константы
	private static final int SCROLL_BUTTON_SIZE = 60;
	private static final int AGE_18_YEARS = 18;

	/**
	 * Дефолтный конструктор
	 */
	public GamesListPage(){
		super(h2TextLocator, "Игры", "Страница списка игр");
	}

	/**
	 * Сверяет конечную цену игры в списке игр и на странице с игрой
	 * @param finalPrice ожидаемая цена, которая показывается в списке игр
	 */
	public void checkGamePrice(String finalPrice) {
		String actualPrice = new TextBox(By.xpath("//div[@class='discount_final_price']")).getElement().getText();
		assertEquals("Не корректна финальная цена на игру!", finalPrice, actualPrice);
		info("Финальная цена на игру корректна: "+actualPrice);
	}

	/**
	 * Считывает данные игр со страницы и записывает их в массив ArrayList<Game>
	 * @param gameLocator локатор игры в списке
	 * @param titleLtr локатор названия игры
	 * @param discLtr локатор скидки
	 * @param origPriceLrt локатор начальной цены
	 * @param finalPriceLtr локатор конечной цены
	 * @param gameUrlLtr локатор ссылки игры
	 * @return массив ArrayList<Game>, содержащий информацию о каждой игре
	 */
	public ArrayList<Game> collectGamesData(String gameLocator, String titleLtr, String discLtr,
				String origPriceLrt, String finalPriceLtr, String gameUrlLtr){
		// объявляем массив игр
		ArrayList<Game> resultsArrList = new ArrayList<Game>();

		// находим все игры в списке
		List<WebElement> list = browser.getDriver().findElements(By.xpath(gameLocator));
		String name, discPct, origPrice, finalPrice, gameUrl, discountTemp = null;
		Double discountDouble = null;

		// заполняем массив игр данными о каждой игре
		for (WebElement el:list){
			name = el.findElement(By.xpath("."+titleLtr)).getText();
			discPct = el.findElement(By.xpath("."+discLtr)).getText();
			discountTemp = discPct.replace("%", "");
			discountDouble = Double.valueOf(discountTemp);
			origPrice = el.findElement(By.xpath("."+origPriceLrt)).getText();
			finalPrice = el.findElement(By.xpath("."+finalPriceLtr)).getText();
			gameUrl = el.findElement(By.xpath("."+gameUrlLtr)).getAttribute("href");

			resultsArrList.add(new Game(name, discPct, discountDouble, origPrice, finalPrice, gameUrl));
		}
		return resultsArrList;
	}

	/**
	 * Подсчитывает число найденных элементов в массиве List<WebElement>
	 * @return число найденных элементов
	 */
	public String countItemsInDiscountList(){
		List<WebElement> items = browser.getDriver().findElements(By.xpath(discoutItemLocator));
		String size = ""+items.size();
		info("Total items in discount list: "+size);
		return size;
	}

	/**
	 * Проверяет наличие страницы ввода даты рождения и вводит, если она появилась
	 * @param datePattern паттерн для даты
	 * @param separator разделитель дней-месяцев-годов
	 */
	public void checkDateInputPage(String datePattern, String separator){
		info("Проверяем, не открылась ли страница ввода даты рождения...");
		if (new TextBox(h2TextLocator, "Пожалуйста, введите дату вашего рождения",
				"Страница ввода даты родения").isPresent()){
			LogStep();
			info("Вводим дату рождения...");

			// генерируем текущую дату - 18 лет (для совершеннолетия) и парсим ее в строку
			Date shiftedDate = CommonFunctions.increaseDateByXYears(new Date(), -AGE_18_YEARS);
			String date = CommonFunctions.formatDateEnLocation(shiftedDate, datePattern);
			info("Inputting date: "+date);
			String day = date.split(separator)[0];
			String month = date.split(separator)[1];
			String year = date.split(separator)[2];

			// вводим дату в поля формы
			new ComboBox(dateLtr, "ageDay", "age day").selectByText(day);
			new ComboBox(dateLtr, "ageMonth", "age month").selectByText(month);
			new ComboBox(dateLtr, "ageYear", "age year").selectByText(year);
			new Button(By.xpath("//a[contains(@class,'btn_checkout')]"), "Ввод").click();
		}
	}

	/**
	 * Драгает скроллбар btnMediaScrollBar в самое крайнее положение (размер скроллбара - длина самой кнопки)
	 */
	public void dragScrollBarToTheRightEnd(){
		info("Крутим скролл в макс. правое положение");
		if (btnMediaScrollBar.isPresent()){
			int size = btnMediaScrollBar.getElement().getSize().width-SCROLL_BUTTON_SIZE;
			browser.dragElement(btnMediaScrollBar, size);
		}
	}

	/**
	 * Проверяет наличие скриншота в строке прокрутки медиаконтента
	 * @return true, если найден хотя бы 1 скриншот. Иначе - false
	 */
	public boolean isScreenshotPresent(){
		info("Проверяем наличие скриншотов");
		boolean isPresent = false;
		if (txbStripLine.isPresent()){
			String locator = txbStripLine.getLocator()+String.format(divIdContainsLocator, "thumb_screenshot");
			locator = locator.replace("By.xpath:", "").trim();
			List<WebElement> items = browser.getDriver().findElements(By.xpath(locator));
			if (items.size() > 0){
				isPresent = true;
				info(" ....Найден(ы) скриншот(ы)!.....");
				info(".....Число скриншотов: "+items.size()+"....");
			}
		}
		return isPresent;
	}

	/**
	 * Открывает последний в списке медиаконтента скриншот в новом окне (вкладке)
	 */
	@SuppressWarnings("deprecation")
	public void openLastScreen(){
		info("Открываем последний в списке скриншот");
		// можно сразу составить локатор последнего скриншота способом, указанным ниже:
		//String locator = txbStripLine.getLocator()+String.format(divIdContainsLocator, "thumb_screenshot")+"[last()]/img";
		//locator = locator.replace("By.xpath:", "").trim();

		// а можно проверять перебором элементов, как сделано ниже:
		String locator = txbStripLine.getLocator()+String.format(divIdContainsLocator, "thumb");
		locator = locator.replace("By.xpath:", "").trim();
		List<WebElement> list = browser.getDriver().findElements(By.xpath(locator));
		int size = list.size();
		int num = 0;
		locator = locator + "[%d]";

		// перебираем иконки с конца и ищем среди них первый скриншот
		for (int i = size-1; i >=0 ; i--){
			info("Всего найдено иконок: "+size);
			String imgAtt = list.get(i).getAttribute("class");
			if (imgAtt.contains("screenshot")){
				num = i+1;
				info("Последний скрин имеет индекс: "+(num));
				break;
			}
		}

		// открываем найденный скрин
		locator = String.format(locator, num);
		Button screenLast = new Button(By.xpath(locator), "Последний в списке скрин");
		screenLast.clickViaJS();
		browser.sleep(3000L);
		Button bigImg = new Button(divIdContainsLocator+"//img", "highlight_player_area", "Центральная картинка");
		browser.clickAndSwitchToNewWindow(bigImg);
	}

	/**
	 * Переходит по табе с указанным названием
	 * @param tabName название табы
	 */
	public void openGamesTab(String tabName){
		new Button(divOnclickWithTextContainsLocator, "tab", tabName, tabName).click();
	}

	/**
	 * Сохраняет скриншот, который открывается на отдельной странице, в указанный файл
	 * @param fileName название файла для сохранения скриншота
	 */
	public void saveImageToLocation(String fileName){
		String imgSource = new TextBox(By.xpath("//body//img")).getElement().getAttribute("src");
		URL url;
		String path = null;
		try {
			File f = new File(fileName);
			if (!f.exists()){
				f.createNewFile();
			}

			// сохраняем картинку в файл посредством метода из стандартного пакета java
			url = new URL(imgSource);
			BufferedImage  buff = ImageIO.read(url);
			ImageIO.write(buff, "jpg", f);
			path = f.getAbsolutePath();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		info("Скриншот успешно сохранен в файл: "+path);
	}

}
